﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ClassMetadataBrowser.Domain;
using Gl.SettingsManager;
using ClassMedataBrowser.Domain;
using System.Windows.Shapes;
using System.Diagnostics;

namespace ClassMetadataBrowser.ToolControls
{
	public partial class SolutionFiles : UserControl, IConsumerForm
	{
		private readonly Dictionary<int, ProjectFile> _map;
		private readonly DataTable _files;

		private DataGridColumnsManager _columnsManager;
		private IMetadataProvider _provider;
		private SolutionFilesSettings _settings;

		public Button OkButton
		{
			get { return _btnOk; }
		}

		public Button CancelButton
		{
			get { return _btnCancel; }
		}

		public SolutionFiles()
		{
			InitializeComponent();

			_ddlCriteriaType.SelectedIndex = 0;
			_map = new Dictionary<int, ProjectFile>();
			_files = new DataTable();

			_files.Columns.Add(new DataColumn("Id", typeof(int)));
			_files.Columns.Add(new DataColumn("Icon", typeof(Bitmap)));
			_files.Columns.Add(new DataColumn("FileName", typeof(string)));
			_files.Columns.Add(new DataColumn("ProjectName", typeof(string)));
			_files.Columns.Add(new DataColumn("Path", typeof(string)));
			_files.Columns.Add(new DataColumn("Open", typeof(string)));

			_gridFiles.CellDoubleClick += new DataGridViewCellEventHandler(CellDoubleClick);
			_gridFiles.ColumnWidthChanged +=new DataGridViewColumnEventHandler(ColumnWidthChanged);
		}

		private void ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
		{
			if (e.Column.Name == _columnFileName.Name)
				_settings.ColumnFileNameWidth = e.Column.Width;
			else if (e.Column.Name == _columnProjectName.Name)
				_settings.ColumnProjectNameWidth = e.Column.Width;
			else if (e.Column.Name == _columnFullPath.Name)
				_settings.ColumnFullPathWidth = e.Column.Width;
		}

		private void CellDoubleClick(object sender, DataGridViewCellEventArgs e) 
		{
			SelectCurrent(true);
		}

		public void Bind(IMetadataProvider provider)
		{
			_provider = provider;
			_map.Clear();
			_files.Clear();

			if (_settings == null)
				LoadSettings();

			IList<ProjectFile> files = provider.GetApplicableProjectItems(_settings.Extensions.Split(','));
			int identifier = 0;

			foreach (ProjectFile file in files)
			{
				identifier++;
				_map.Add(identifier, file);
				_files.Rows.Add(
					identifier, 
					ProjectFileIconHelper.GetIconForFile(file),
					file.Name,
					file.ProjectName,
					file.FilePath,
					"Open in Explorer");
			}

			FindForm().Text = string.Format(Resources.Showing, _files.DefaultView.Count, _files.Rows.Count);
			_gridFiles.DataSource = _files;
		}

		protected override bool ProcessKeyPreview(ref Message m)
		{
			if (m.Msg == Utils.KeyDownConst)
				switch (m.WParam.ToInt32())
				{
					case 38:
						_gridFiles.ChangeRow(true);
						return true;
					case 40:
						_gridFiles.ChangeRow(false);
						return true;
				}

			return base.ProcessKeyPreview(ref m);
		}

		private void CriteriaTextChanged(object sender, EventArgs e)
		{
			Filter(_txtCriteria.Text, _ddlCriteriaType.SelectedIndex);
		}

		public void SelectCurrent(bool closeWindow)
		{
			if (_gridFiles.SelectedCells.Count > 0)
			{
				foreach (DataGridViewRow selectedRow in _gridFiles.SelectedRows)
				{
					int id = (int)((DataRowView)selectedRow.DataBoundItem)["Id"];
					_map[id].Open();
				}

				if (closeWindow)
				{
					FindForm().DialogResult = DialogResult.OK;
					FindForm().Close();
				}
			}
		}

		private void LoadSettings()
		{
			_settings = new SolutionFilesSettings();


			Settings.GetSettingsWithRegistryProvider().Load(_settings);

			if (!string.IsNullOrEmpty(_settings.CreteriaHistory))
			{
				//AutoCompleteStringCollection collection = new AutoCompleteStringCollection();
				//_settings.CreteriaHistory.Split(',').ToList().ForEach(e => collection.Add(e));
				//_txtCriteria.AutoCompleteCustomSource = collection;
			}

			if (_settings.ColumnFileNameWidth > 0)
				_gridFiles.Columns[_columnFileName.Name].Width = _settings.ColumnFileNameWidth;

			if (_settings.ColumnProjectNameWidth > 0)
				_gridFiles.Columns[_columnProjectName.Name].Width = _settings.ColumnProjectNameWidth;

			if (_settings.ColumnFullPathWidth > 0)
				_gridFiles.Columns[_columnFullPath.Name].Width = _settings.ColumnFullPathWidth;

			if (!string.IsNullOrEmpty(_settings.SearchCriteria))
				_txtCriteria.Text = _settings.SearchCriteria;

			_ddlCriteriaType.SelectedIndex = _settings.SearchModeIndex;
		}

		protected override void OnLoad(EventArgs e)
		{
			LoadSettings();
			base.OnLoad(e);
			_txtCriteria.Focus();
		}

		protected override void OnLostFocus(EventArgs e)
		{
			// saving settings
			Settings.GetSettingsWithRegistryProvider().Save(this);
			base.OnLostFocus(e);
		}

		private void BtnExtensionsClick(object sender, EventArgs e)
		{
			ExtensionsForm extensions = new ExtensionsForm();
			extensions.InitializeExtensionsString(_settings.Extensions);
			if (extensions.ShowDialog() == DialogResult.OK)
			{
				_settings.Extensions = extensions.GetExtensions();
				Bind(_provider);
			}
		}

		private void CriteriaKeyPress(object sender, KeyPressEventArgs e)
		{
			if (e.KeyChar == 13)
			{
				SelectCurrent(true);
				e.Handled = true;
			}
		}

		public void SaveSettings()
		{
			if (_txtCriteria.AutoCompleteCustomSource.Count > 10)
			{
				_txtCriteria.AutoCompleteCustomSource.RemoveAt(0);
				_txtCriteria.AutoCompleteCustomSource.Insert(0, _txtCriteria.Text);
				_settings.CreteriaHistory = string.Join(",", _txtCriteria.AutoCompleteCustomSource.OfType<string>().ToArray()).Trim(',');
			}
			else
				_settings.CreteriaHistory = string.Join(",", _txtCriteria.AutoCompleteCustomSource.OfType<string>().ToArray()).Trim(',') + ',' + _txtCriteria.Text;

			_settings.SearchModeIndex = _ddlCriteriaType.SelectedIndex;
			Settings.GetSettingsWithRegistryProvider().Save(_settings);
		}

		public void SetFocusOnCriteria()
		{
			_txtCriteria.Focus();
			_txtCriteria.Select();
			ActiveControl = _txtCriteria;
		}

		private void CellContentClicked(object sender, DataGridViewCellEventArgs e)
		{
			if (_gridFiles.Columns[e.ColumnIndex].Name == _columnExploreFile.Name)
			{
				string fileName = ((DataRowView)_gridFiles.Rows[e.RowIndex].DataBoundItem)["Path"].ToString();
				Process.Start("explorer.exe", string.Format("/select,{0}", fileName));
			}
		}

		private void SolutionFilesKeyEnter(object sender, KeyEventArgs e)
		{
			if ((e.KeyCode & e.KeyData) == Keys.Enter)
				e.SuppressKeyPress = true;
		}

		private void BtnConfigureClick(object sender, EventArgs e)
		{
			ConfigurationWindow configurationWindow = new ConfigurationWindow();
			configurationWindow.AcceptColumnsManager(_columnsManager);
			configurationWindow.ShowDialog();
		}

		public void AcceptColumnDescriptor(ColumnsDescriptor descriptor)
		{
			_columnsManager = new DataGridColumnsManager(_gridFiles, descriptor);
		}

		private void DdlCriteriaTypeSelectedIndexChanged(object sender, EventArgs e)
		{
			Filter(_txtCriteria.Text, _ddlCriteriaType.SelectedIndex);
		}

		private void Filter(string criteria, int filterMode)
		{
			if (_files == null)
				return;

			switch(filterMode)
			{
				case 0:
					_files.DefaultView.RowFilter = string.Format("FileName like '%{0}%'", criteria);
				break;
				case 1:
					_files.DefaultView.RowFilter = string.Format("FileName like '{0}%'", criteria);
				break;
			}

			FindForm().Text = string.Format(Resources.Showing, _files.Rows.Count, _files.DefaultView.Count);
			_settings.SearchCriteria = _txtCriteria.Text;
		}
	}
}
